package abstractfactory;

import abstractfactory.factory.AbstractFactory;
import abstractfactory.factory.impl.ConcreteFactory1;
import abstractfactory.factory.impl.ConcreteFactory2;
import abstractfactory.product.AbstractProductA;
import abstractfactory.product.AbstractProductB;

/**
 * 抽象工厂模式主程序
 * 抽象工厂模式 (Abstract Factory Pattern)旨在提供一个接口，用于创建一系列相关或相互依赖的对象家族，而无需指定它们具体的类。
 * 简而言之，抽象工厂是一个工厂的工厂。
 * 这里抽象工厂为{@link AbstractFactory}，有两个实现{@link ConcreteFactory1} 生产1风格的产品，
 * {@link ConcreteFactory2} 生产2风格的产品。
 * {@link AbstractProductA} 和  {@link AbstractProductB} 表示 A 产品和B 产品
 * 具体的实现则分为A1、A2、B1、B2，这样的四个产品矩阵。
 * 这样用户就无需了解具体的产品和风格是如何生产的，只需要输如想要产品和风格即可获得对应的产品。
 *
 * @author Liu Yicong
 * @date 2025/9/21
 */
public class AFClient {
	// 客户端代码只依赖于 AbstractFactory 接口
	public static void clientMethod(AbstractFactory factory) {
		AbstractProductA productA = factory.createProductA();
		AbstractProductB productB = factory.createProductB();

		System.out.println("--- 使用工厂: " + factory.getClass().getSimpleName() + " ---");
		System.out.println("  -> 创建产品 A: " + productA.getName());
		System.out.println("  -> 创建产品 B: " + productB.getName());
	}

	public static void main(String[] args) {
		// 场景 1: 使用 ConcreteFactory1 创建产品族 1
		AbstractFactory factory1 = new ConcreteFactory1();
		clientMethod(factory1);

		System.out.println("\n===================================");

		// 场景 2: 切换到 ConcreteFactory2，产品族也随之切换
		AbstractFactory factory2 = new ConcreteFactory2();
		clientMethod(factory2);
	}
}
